/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
#define BOOST_TEST_MAIN

#define BOOST_TEST_MODULE threecenter_dft_test
#include <boost/test/unit_test.hpp>
#include <votca/tools/tokenizer.h>
#include <votca/xtp/aobasis.h>
#include <votca/xtp/qmmolecule.h>
#include <votca/xtp/threecenter.h>

using namespace votca::xtp;
using namespace votca;

BOOST_AUTO_TEST_SUITE(threecenter_dft_test)

Eigen::MatrixXd ReadMatrixFromString(const std::string& matrix) {
  votca::tools::Tokenizer lines(matrix, "\n");

  std::vector<double> entries;
  Index cols = 0;
  Index rows = 0;
  for (auto line : lines) {
    if (line[0] == '#') {
      continue;
    }
    votca::tools::Tokenizer entries_tok(line, " ");
    std::vector<std::string> temp = entries_tok.ToVector();
    cols = Index(temp.size());
    rows++;
    for (const auto& s : temp) {
      entries.push_back(std::stod(s));
    }
  }

  return Eigen::Map<Eigen::MatrixXd>(entries.data(), rows, cols);
}

BOOST_AUTO_TEST_CASE(small_basis) {

  OPENMP::setMaxThreads(1);

  std::ofstream xyzfile("molecule.xyz");
  xyzfile << " 5" << std::endl;
  xyzfile << " methane" << std::endl;
  xyzfile << " C            .000000     .000000     .000000" << std::endl;
  xyzfile << " H            .629118     .629118     .629118" << std::endl;
  xyzfile << " H           -.629118    -.629118     .629118" << std::endl;
  xyzfile << " H            .629118    -.629118    -.629118" << std::endl;
  xyzfile << " H           -.629118     .629118    -.629118" << std::endl;
  xyzfile.close();

  std::ofstream basisfile("3-21G.xml");
  basisfile << "<basis name=\"3-21G\">" << std::endl;
  basisfile << "  <element name=\"H\">" << std::endl;
  basisfile << "    <shell scale=\"1.0\" type=\"S\">" << std::endl;
  basisfile << "      <constant decay=\"5.447178e+00\">" << std::endl;
  basisfile << "        <contractions factor=\"1.562850e-01\" type=\"S\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "      <constant decay=\"8.245470e-01\">" << std::endl;
  basisfile << "        <contractions factor=\"9.046910e-01\" type=\"S\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "    </shell>" << std::endl;
  basisfile << "    <shell scale=\"1.0\" type=\"S\">" << std::endl;
  basisfile << "      <constant decay=\"1.831920e-01\">" << std::endl;
  basisfile << "        <contractions factor=\"1.000000e+00\" type=\"S\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "    </shell>" << std::endl;
  basisfile << "  </element>" << std::endl;
  basisfile << "  <element name=\"C\">" << std::endl;
  basisfile << "    <shell scale=\"1.0\" type=\"S\">" << std::endl;
  basisfile << "      <constant decay=\"1.722560e+02\">" << std::endl;
  basisfile << "        <contractions factor=\"6.176690e-02\" type=\"S\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "      <constant decay=\"2.591090e+01\">" << std::endl;
  basisfile << "        <contractions factor=\"3.587940e-01\" type=\"S\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "      <constant decay=\"5.533350e+00\">" << std::endl;
  basisfile << "        <contractions factor=\"7.007130e-01\" type=\"S\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "    </shell>" << std::endl;
  basisfile << "    <shell scale=\"1.0\" type=\"SP\">" << std::endl;
  basisfile << "      <constant decay=\"3.664980e+00\">" << std::endl;
  basisfile << "        <contractions factor=\"-3.958970e-01\" type=\"S\"/>"
            << std::endl;
  basisfile << "        <contractions factor=\"2.364600e-01\" type=\"P\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "      <constant decay=\"7.705450e-01\">" << std::endl;
  basisfile << "        <contractions factor=\"1.215840e+00\" type=\"S\"/>"
            << std::endl;
  basisfile << "        <contractions factor=\"8.606190e-01\" type=\"P\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "    </shell>" << std::endl;
  basisfile << "    <shell scale=\"1.0\" type=\"SP\">" << std::endl;
  basisfile << "      <constant decay=\"1.958570e-01\">" << std::endl;
  basisfile << "        <contractions factor=\"1.000000e+00\" type=\"S\"/>"
            << std::endl;
  basisfile << "        <contractions factor=\"1.000000e+00\" type=\"P\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "    </shell>" << std::endl;
  basisfile << "  </element>" << std::endl;
  basisfile << "</basis>" << std::endl;
  basisfile.close();

  QMMolecule mol(" ", 0);
  mol.LoadFromFile("molecule.xyz");
  BasisSet basis;
  basis.Load("3-21G.xml");
  AOBasis aobasis;
  aobasis.Fill(basis, mol);
  TCMatrix_dft threec;
  threec.Fill(aobasis, aobasis);

  std::string ref0_string =
      " 1.60933 0.156026 7.9158e-17 -7.38386e-18 9.11858e-18 0.203748 "
      "1.01459e-17 -9.03068e-19 1.17412e-18 0.0195044 0.0905022 0.0195044 "
      "0.0905022 0.0195044 0.0905022 0.0195044 0.0905022\n"
      " 0.156026 0.189689 7.23701e-17 3.09035e-18 1.07874e-17 0.112228 "
      "-2.62193e-17 1.19079e-17 -2.80057e-18 0.0156068 0.0516639 0.0156068 "
      "0.0516639 0.0156068 0.0516639 0.0156068 0.0516639\n"
      " 7.9158e-17 7.23701e-17 0.252489 1.04726e-19 -3.57417e-18 -7.11809e-18 "
      "0.0409547 6.87544e-19 -3.72331e-18 0.00993143 0.00923661 0.00993143 "
      "0.00923661 -0.00993143 -0.00923661 -0.00993143 -0.00923661\n"
      "-7.38386e-18 3.09035e-18 1.04726e-19 0.252489 -5.09944e-18 1.27559e-17 "
      "6.87544e-19 0.0409547 1.26138e-17 0.00993143 0.00923661 -0.00993143 "
      "-0.00923661 -0.00993143 -0.00923661 0.00993143 0.00923661\n"
      " 9.11858e-18 1.07874e-17 -3.57417e-18 -5.09944e-18 0.252489 "
      "-6.12873e-19 -3.72331e-18 1.26138e-17 0.0409547 0.00993143 0.00923661 "
      "-0.00993143 -0.00923661 0.00993143 0.00923661 -0.00993143 -0.00923661\n"
      " 0.203748 0.112228 -7.11809e-18 1.27559e-17 -6.12873e-19 0.0739222 "
      "-1.00337e-16 4.22242e-17 -2.31423e-17 0.0109019 0.0339426 0.0109019 "
      "0.0339426 0.0109019 0.0339426 0.0109019 0.0339426\n"
      " 1.01459e-17 -2.62193e-17 0.0409547 6.87544e-19 -3.72331e-18 "
      "-1.00337e-16 0.00662462 8.67362e-18 -1.70764e-17 0.00383329 0.00241774 "
      "0.00383329 0.00241774 -0.00383329 -0.00241774 -0.00383329 -0.00241774\n"
      "-9.03068e-19 1.19079e-17 6.87544e-19 0.0409547 1.26138e-17 4.22242e-17 "
      "8.67362e-18 0.00662462 1.7331e-16 0.00383329 0.00241774 -0.00383329 "
      "-0.00241774 -0.00383329 -0.00241774 0.00383329 0.00241774\n"
      " 1.17412e-18 -2.80057e-18 -3.72331e-18 1.26138e-17 0.0409547 "
      "-2.31423e-17 -1.70764e-17 1.7331e-16 0.00662462 0.00383329 0.00241774 "
      "-0.00383329 -0.00241774 0.00383329 0.00241774 -0.00383329 -0.00241774\n"
      " 0.0195044 0.0156068 0.00993143 0.00993143 0.00993143 0.0109019 "
      "0.00383329 0.00383329 0.00383329 0.0143735 0.0108626 0.000680431 "
      "0.00420737 0.000680431 0.00420737 0.000680431 0.00420737\n"
      " 0.0905022 0.0516639 0.00923661 0.00923661 0.00923661 0.0339426 "
      "0.00241774 0.00241774 0.00241774 0.0108626 0.019639 0.00420737 "
      "0.0149384 0.00420737 0.0149384 0.00420737 0.0149384\n"
      " 0.0195044 0.0156068 0.00993143 -0.00993143 -0.00993143 0.0109019 "
      "0.00383329 -0.00383329 -0.00383329 0.000680431 0.00420737 0.0143735 "
      "0.0108626 0.000680431 0.00420737 0.000680431 0.00420737\n"
      " 0.0905022 0.0516639 0.00923661 -0.00923661 -0.00923661 0.0339426 "
      "0.00241774 -0.00241774 -0.00241774 0.00420737 0.0149384 0.0108626 "
      "0.019639 0.00420737 0.0149384 0.00420737 0.0149384\n"
      " 0.0195044 0.0156068 -0.00993143 -0.00993143 0.00993143 0.0109019 "
      "-0.00383329 -0.00383329 0.00383329 0.000680431 0.00420737 0.000680431 "
      "0.00420737 0.0143735 0.0108626 0.000680431 0.00420737\n"
      " 0.0905022 0.0516639 -0.00923661 -0.00923661 0.00923661 0.0339426 "
      "-0.00241774 -0.00241774 0.00241774 0.00420737 0.0149384 0.00420737 "
      "0.0149384 0.0108626 0.019639 0.00420737 0.0149384\n"
      " 0.0195044 0.0156068 -0.00993143 0.00993143 -0.00993143 0.0109019 "
      "-0.00383329 0.00383329 -0.00383329 0.000680431 0.00420737 0.000680431 "
      "0.00420737 0.000680431 0.00420737 0.0143735 0.0108626\n"
      " 0.0905022 0.0516639 -0.00923661 0.00923661 -0.00923661 0.0339426 "
      "-0.00241774 0.00241774 -0.00241774 0.00420737 0.0149384 0.00420737 "
      "0.0149384 0.00420737 0.0149384 0.0108626 0.019639";

  Eigen::MatrixXd Ref0 = ReadMatrixFromString(ref0_string);
  std::string ref4_string =
      "6.10201e-16 1.04083e-16 -1.43471e-17 2.38881e-17 0.115582 9.92184e-17 "
      "-2.22379e-18 3.68746e-18 0.0159 0.00332761 0.00350516 -0.00332761 "
      "-0.00350516 0.00332761 0.00350516 -0.00332761 -0.00350516\n"
      " 1.04083e-16 5.55112e-16 -1.17237e-16 1.90095e-16 0.400942 4.38974e-16 "
      "-6.62885e-17 1.14861e-16 0.160429 0.0438354 0.0379715 -0.0438354 "
      "-0.0379715 0.0438354 0.0379715 -0.0438354 -0.0379715\n"
      "-1.43471e-17 -1.17237e-16 5.00192e-16 -0.0118561 -3.89039e-17 "
      "-1.00727e-16 3.02627e-16 -0.00838998 -3.17098e-17 0.0247852 0.00498474 "
      "-0.0247852 -0.00498474 -0.0247852 -0.00498474 0.0247852 0.00498474\n"
      " 2.38881e-17 1.90095e-16 -0.0118561 5.00192e-16 -9.12004e-17 "
      "1.80524e-16 -0.00838998 3.02627e-16 -6.93378e-17 0.0247852 0.00498474 "
      "0.0247852 0.00498474 -0.0247852 -0.00498474 -0.0247852 -0.00498474\n"
      " 0.115582 0.400942 -3.89039e-17 -9.12004e-17 5.00192e-16 0.283457 "
      "-3.17098e-17 -6.93378e-17 3.02627e-16 0.0620134 0.144146 0.0620134 "
      "0.144146 0.0620134 0.144146 0.0620134 0.144146\n"
      " 9.92184e-17 4.38974e-16 -1.00727e-16 1.80524e-16 0.283457 5.86928e-16 "
      "-1.21176e-16 2.53015e-16 0.150009 0.0408784 0.0355068 -0.0408784 "
      "-0.0355068 0.0408784 0.0355068 -0.0408784 -0.0355068\n"
      "-2.22379e-18 -6.62885e-17 3.02627e-16 -0.00838998 -3.17098e-17 "
      "-1.21176e-16 5.82867e-16 -0.0119247 -8.61934e-17 0.0165925 0.00164473 "
      "-0.0165925 -0.00164473 -0.0165925 -0.00164473 0.0165925 0.00164473\n"
      " 3.68746e-18 1.14861e-16 -0.00838998 3.02627e-16 -6.93378e-17 "
      "2.53015e-16 -0.0119247 5.82867e-16 -1.4626e-16 0.0165925 0.00164473 "
      "0.0165925 0.00164473 -0.0165925 -0.00164473 -0.0165925 -0.00164473\n"
      " 0.0159 0.160429 -3.17098e-17 -6.93378e-17 3.02627e-16 0.150009 "
      "-8.61934e-17 -1.4626e-16 5.55937e-16 0.0403597 0.0808243 0.0403597 "
      "0.0808243 0.0403597 0.0808243 0.0403597 0.0808243\n"
      " 0.00332761 0.0438354 0.0247852 0.0247852 0.0620134 0.0408784 0.0165925 "
      "0.0165925 0.0403597 0.0699398 0.0446004 3.11592e-18 0.0118855 "
      "0.00334514 0.0207078 7.06088e-18 0.0118855\n"
      " 0.00350516 0.0379715 0.00498474 0.00498474 0.144146 0.0355068 "
      "0.00164473 0.00164473 0.0808243 0.0446004 0.0387592 -0.0118855 "
      "1.61347e-16 0.0207078 0.0350755 -0.0118855 2.86438e-16\n"
      " -0.00332761 -0.0438354 -0.0247852 0.0247852 0.0620134 -0.0408784 "
      "-0.0165925 0.0165925 0.0403597 3.11592e-18 -0.0118855 -0.0699398 "
      "-0.0446004 1.59804e-18 -0.0118855 -0.00334514 -0.0207078\n"
      " -0.00350516 -0.0379715 -0.00498474 0.00498474 0.144146 -0.0355068 "
      "-0.00164473 0.00164473 0.0808243 0.0118855 1.61347e-16 -0.0446004 "
      "-0.0387592 0.0118855 1.16578e-16 -0.0207078 -0.0350755\n"
      " 0.00332761 0.0438354 -0.0247852 -0.0247852 0.0620134 0.0408784 "
      "-0.0165925 -0.0165925 0.0403597 0.00334514 0.0207078 1.59804e-18 "
      "0.0118855 0.0699398 0.0446004 5.75984e-18 0.0118855\n"
      " 0.00350516 0.0379715 -0.00498474 -0.00498474 0.144146 0.0355068 "
      "-0.00164473 -0.00164473 0.0808243 0.0207078 0.0350755 -0.0118855 "
      "1.16578e-16 0.0446004 0.0387592 -0.0118855 2.30927e-16\n"
      " -0.00332761 -0.0438354 0.0247852 -0.0247852 0.0620134 -0.0408784 "
      "0.0165925 -0.0165925 0.0403597 7.06088e-18 -0.0118855 -0.00334514 "
      "-0.0207078 5.75984e-18 -0.0118855 -0.0699398 -0.0446004\n"
      " -0.00350516 -0.0379715 0.00498474 -0.00498474 0.144146 -0.0355068 "
      "0.00164473 -0.00164473 0.0808243 0.0118855 2.86438e-16 -0.0207078 "
      "-0.0350755 0.0118855 2.30927e-16 -0.0446004 -0.0387592";

  Eigen::MatrixXd Ref4 = ReadMatrixFromString(ref4_string);

  bool check_three1 = Ref0.isApprox(threec[0].FullMatrix(), 0.00001);
  if (!check_three1) {
    std::cout << "Res0" << std::endl;
    std::cout << threec[0].FullMatrix() << std::endl;
    std::cout << "0_ref" << std::endl;
    std::cout << Ref0 << std::endl;
  }
  BOOST_CHECK_EQUAL(check_three1, true);
  bool check_three2 = Ref4.isApprox(threec[4].FullMatrix(), 0.00001);
  if (!check_three2) {
    std::cout << "Res4" << std::endl;
    std::cout << threec[4].FullMatrix() << std::endl;
    std::cout << "4_ref" << std::endl;
    std::cout << Ref4 << std::endl;
  }
  BOOST_CHECK_EQUAL(check_three2, true);
}

BOOST_AUTO_TEST_CASE(large_l_test) {
  OPENMP::setMaxThreads(1);
  std::ofstream xyzfile("C2.xyz");
  xyzfile << " 2" << std::endl;
  xyzfile << " C2" << std::endl;
  xyzfile << " C            .000000     .000000     .000000" << std::endl;
  xyzfile << " C            1.000000     .000000     .000000" << std::endl;
  xyzfile.close();

  QMMolecule mol("C", 0);
  mol.LoadFromFile("C2.xyz");

  std::ofstream basisfile("G.xml");
  basisfile << "<basis name=\"G\">" << std::endl;
  basisfile << "  <element name=\"C\">" << std::endl;
  basisfile << "    <shell scale=\"1.0\" type=\"G\">" << std::endl;
  basisfile << "      <constant decay=\"5.447178e+00\">" << std::endl;
  basisfile << "        <contractions factor=\"1.562850e-01\" type=\"G\"/>"
            << std::endl;
  basisfile << "      </constant>" << std::endl;
  basisfile << "    </shell>" << std::endl;
  basisfile << "  </element>" << std::endl;
  basisfile << "</basis>" << std::endl;
  basisfile.close();

  std::ofstream auxbasisfile("I.xml");
  auxbasisfile << "<basis name=\"I\">" << std::endl;
  auxbasisfile << "  <element name=\"C\">" << std::endl;
  auxbasisfile << "    <shell scale=\"1.0\" type=\"I\">" << std::endl;
  auxbasisfile << "      <constant decay=\"5.447178e+00\">" << std::endl;
  auxbasisfile << "        <contractions factor=\"1.562850e-01\" type=\"I\"/>"
               << std::endl;
  auxbasisfile << "      </constant>" << std::endl;
  auxbasisfile << "    </shell>" << std::endl;
  auxbasisfile << "  </element>" << std::endl;
  auxbasisfile << "</basis>" << std::endl;
  auxbasisfile.close();

  BasisSet basisset;
  basisset.Load("G.xml");
  AOBasis dftbasis;
  dftbasis.Fill(basisset, mol);
  BasisSet auxbasisset;
  auxbasisset.Load("I.xml");
  AOBasis auxbasis;
  auxbasis.Fill(auxbasisset, mol);

  TCMatrix_dft threec;
  threec.Fill(auxbasis, dftbasis);
  // we only test half of it because it gets a bit big
  std::array<Eigen::MatrixXd, 4> ref;
  std::array<std::string, 4> ref_string;

  ref_string[0] =
      " 0.0813694 1.21921e-19 -6.67319e-20 0.000255871 -0.000368408 "
      "-1.69226e-19 8.86939e-20 -4.85634e-05 3.20907e-05 -0.000890999 "
      "-3.99401e-22 2.69842e-21 -5.91818e-06 0.00122546 8.12218e-22 "
      "-1.85631e-21 1.18137e-05 -0.00132349\n"
      " 1.21921e-19 -0.00300879 -0.000183283 1.39412e-20 1.8567e-20 "
      "-0.00046873 -0.000113122 -1.97911e-20 -2.31653e-19 -2.24577e-22 "
      "3.21609e-05 3.23495e-06 -2.95529e-22 2.42129e-22 -0.000107498 "
      "-1.59518e-06 8.85921e-22 1.55986e-22\n"
      "-6.67319e-20 -0.000183283 -0.00301615 1.84691e-19 -8.87006e-20 "
      "0.000222699 -0.000510301 6.14499e-20 -1.63723e-19 -2.81792e-21 "
      "-3.31055e-06 -0.000591671 -9.95227e-22 4.81524e-21 8.41652e-06 "
      "0.000648742 1.41146e-21 -8.83074e-21\n"
      " 0.000255871 1.39412e-20 1.84691e-19 -0.087344 -6.31827e-05 4.45592e-20 "
      "1.74272e-19 -0.000118643 -0.000130532 5.79545e-06 4.32193e-22 "
      "-6.61661e-22 0.000466426 -6.4717e-06 -9.59239e-22 -4.64811e-23 "
      "-0.00100822 1.32816e-06\n"
      "-0.000368408 1.8567e-20 -8.87006e-20 -6.31827e-05 -0.0872068 "
      "-9.31614e-20 1.13089e-19 0.000129546 -0.00016663 0.00115455 4.92141e-22 "
      "-4.84529e-21 6.68228e-06 -0.00160487 -9.72892e-22 3.66195e-21 "
      "-1.49108e-05 0.00176922\n"
      "-1.69226e-19 -0.00046873 0.000222699 4.45592e-20 -9.31614e-20 0.0694623 "
      "1.96013e-06 7.90463e-22 -6.12856e-20 6.06213e-22 -0.000105821 "
      "-8.22404e-06 8.96139e-22 -7.12387e-22 0.000352313 4.60011e-06 "
      "-2.68399e-21 -1.04111e-22\n"
      " 8.86939e-20 -0.000113122 -0.000510301 1.74272e-19 1.13089e-19 "
      "1.96013e-06 0.0694836 6.03332e-20 1.91284e-21 2.45391e-21 1.68297e-06 "
      "0.000611142 7.18169e-22 -4.35397e-21 -4.84092e-06 -0.000719351 "
      "-8.86829e-22 8.52525e-21\n"
      "-4.85634e-05 -1.97911e-20 6.14499e-20 -0.000118643 0.000129546 "
      "7.90463e-22 6.03332e-20 -0.0143026 -1.74412e-06 -1.15682e-05 "
      "-1.45451e-21 2.24325e-21 -0.000855248 1.44396e-05 3.34911e-21 "
      "-3.75641e-22 0.00144364 -7.45132e-06\n"
      " 3.20907e-05 -2.31653e-19 -1.63723e-19 -0.000130532 -0.00016663 "
      "-6.12856e-20 1.91284e-21 -1.74412e-06 -0.0143258 -0.00106106 "
      "-2.08579e-22 9.96766e-21 -1.68617e-06 0.00150178 2.56404e-22 "
      "-8.7038e-21 8.50369e-06 -0.00148161\n"
      "-0.000890999 -2.24577e-22 -2.81792e-21 5.79545e-06 0.00115455 "
      "6.06213e-22 2.45391e-21 -1.15682e-05 -0.00106106 -0.00994595 "
      "4.06955e-20 -1.81051e-19 -0.000348414 0.00276106 2.18459e-19 "
      "6.99607e-20 6.64906e-05 -0.000942407\n"
      "-3.99401e-22 3.21609e-05 -3.31055e-06 4.32193e-22 4.92141e-22 "
      "-0.000105821 1.68297e-06 -1.45451e-21 -2.08579e-22 4.06955e-20 "
      "-0.00672396 0.000250442 -8.27277e-20 -1.56997e-19 0.00168277 "
      "0.000154644 -1.03284e-19 3.19687e-19\n"
      " 2.69842e-21 3.23495e-06 -0.000591671 -6.61661e-22 -4.84529e-21 "
      "-8.22404e-06 0.000611142 2.24325e-21 9.96766e-21 -1.81051e-19 "
      "0.000250442 -0.00765158 -1.0287e-19 -1.62451e-19 -0.000301095 "
      "0.00149804 -7.01564e-20 -2.46921e-21\n"
      "-5.91818e-06 -2.95529e-22 -9.95227e-22 0.000466426 6.68228e-06 "
      "8.96139e-22 7.18169e-22 -0.000855248 -1.68617e-06 -0.000348414 "
      "-8.27277e-20 -1.0287e-19 -0.00642127 8.30795e-05 2.16233e-19 "
      "-1.74692e-20 0.00466022 0.00017558\n"
      " 0.00122546 2.42129e-22 4.81524e-21 -6.4717e-06 -0.00160487 "
      "-7.12387e-22 -4.35397e-21 1.44396e-05 0.00150178 0.00276106 "
      "-1.56997e-19 -1.62451e-19 8.30795e-05 -0.00809455 -1.06038e-19 "
      "1.68828e-19 -0.000177806 0.00520077\n"
      " 8.12218e-22 -0.000107498 8.41652e-06 -9.59239e-22 -9.72892e-22 "
      "0.000352313 -4.84092e-06 3.34911e-21 2.56404e-22 2.18459e-19 0.00168277 "
      "-0.000301095 2.16233e-19 -1.06038e-19 -0.00896904 7.67552e-07 "
      "-8.45039e-20 -1.61592e-20\n"
      "-1.85631e-21 -1.59518e-06 0.000648742 -4.64811e-23 3.66195e-21 "
      "4.60011e-06 -0.000719351 -3.75641e-22 -8.7038e-21 6.99607e-20 "
      "0.000154644 0.00149804 -1.74692e-20 1.68828e-19 7.67552e-07 -0.00899039 "
      "1.71012e-20 -8.86859e-20\n"
      " 1.18137e-05 8.85921e-22 1.41146e-21 -0.00100822 -1.49108e-05 "
      "-2.68399e-21 -8.86829e-22 0.00144364 8.50369e-06 6.64906e-05 "
      "-1.03284e-19 -7.01564e-20 0.00466022 -0.000177806 -8.45039e-20 "
      "1.71012e-20 -0.0192904 9.39644e-07\n"
      " -0.00132349 1.55986e-22 -8.83074e-21 1.32816e-06 0.00176922 "
      "-1.04111e-22 8.52525e-21 -7.45132e-06 -0.00148161 -0.000942407 "
      "3.19687e-19 -2.46921e-21 0.00017558 0.00520077 -1.61592e-20 "
      "-8.86859e-20 9.39644e-07 -0.019062";

  ref_string[1] =
      "-5.43523e-17 0.0581771 1.28112e-17 -1.56812e-18 4.5967e-18 7.65466e-05 "
      "-5.50132e-19 -2.67696e-18 9.00625e-18 -4.2557e-19 -6.84184e-05 "
      "3.18125e-20 -9.41754e-20 5.47042e-19 0.000162848 -2.16955e-20 "
      "2.98515e-19 -3.53837e-19\n"
      " 0.0581771 -5.30631e-17 6.31086e-18 7.64125e-18 -0.0390494 3.46556e-18 "
      "-5.64649e-18 -2.53662e-17 -4.64876e-05 -0.00010165 -7.99358e-20 "
      "1.304e-19 -7.25741e-20 0.000130282 2.05121e-19 -9.17829e-20 1.76009e-19 "
      "-6.01776e-05\n"
      " 1.28112e-17 6.31086e-18 -5.68161e-17 0.0389678 8.54736e-18 4.40636e-18 "
      "6.29327e-18 2.58404e-05 2.97988e-17 -2.02598e-20 -1.39168e-19 "
      "1.24658e-18 -0.000221617 -1.1498e-19 3.87322e-19 -1.03433e-18 "
      "0.000653992 9.72262e-19\n"
      "-1.56812e-18 7.64125e-18 0.0389678 -4.99589e-17 2.34453e-18 "
      "-1.51622e-18 0.0639804 -1.16248e-18 1.88954e-17 9.98969e-20 5.42783e-20 "
      "-0.000236757 2.35927e-19 -1.73459e-19 -1.0818e-19 0.000125724 "
      "-4.89225e-19 2.37476e-19\n"
      " 4.5967e-18 -0.0390494 8.54736e-18 2.34453e-18 -6.16283e-17 -0.0639315 "
      "-2.86172e-17 8.55423e-18 2.76038e-18 5.40981e-19 8.00951e-05 "
      "1.06257e-19 1.68036e-19 -7.4701e-19 -0.000198317 -1.14083e-19 "
      "-5.13226e-19 6.74611e-19\n"
      " 7.65466e-05 3.46556e-18 4.40636e-18 -1.51622e-18 -0.0639315 "
      "-5.49077e-17 -1.82847e-17 3.85147e-18 -0.0259588 0.000214762 2.0558e-19 "
      "-3.85377e-19 1.32678e-19 -0.000283019 -5.60102e-19 2.75892e-19 "
      "-3.05564e-19 0.000153394\n"
      "-5.50132e-19 -5.64649e-18 6.29327e-18 0.0639804 -2.86172e-17 "
      "-1.82847e-17 -6.0067e-17 0.0259281 3.29362e-18 -4.08831e-20 1.06802e-19 "
      "-1.07791e-18 6.09088e-05 2.02004e-19 -3.01332e-19 1.03987e-18 "
      "-0.000247983 -1.04095e-18\n"
      "-2.67696e-18 -2.53662e-17 2.58404e-05 -1.16248e-18 8.55423e-18 "
      "3.85147e-18 0.0259281 -5.99519e-17 -2.321e-20 -3.32131e-19 -1.18187e-19 "
      "0.000571075 -4.51091e-19 5.55723e-19 2.1991e-19 -0.000311016 "
      "1.48718e-18 -7.27807e-19\n"
      " 9.00625e-18 -4.64876e-05 2.97988e-17 1.88954e-17 2.76038e-18 "
      "-0.0259588 3.29362e-18 -2.321e-20 -5.97415e-17 -3.59704e-19 "
      "-2.55361e-06 -1.10655e-18 -2.46058e-19 6.94632e-19 4.23149e-05 "
      "1.05022e-18 7.37562e-19 -1.53758e-18\n"
      " -4.2557e-19 -0.00010165 -2.02598e-20 9.98969e-20 5.40981e-19 "
      "0.000214762 -4.08831e-20 -3.32131e-19 -3.59704e-19 -5.85111e-17 "
      "-0.000279182 4.41282e-18 -3.00215e-18 3.77869e-18 -0.00107761 "
      "3.97249e-19 1.00303e-17 -7.52114e-18\n"
      "-6.84184e-05 -7.99358e-20 -1.39168e-19 5.42783e-20 8.00951e-05 "
      "2.0558e-19 1.06802e-19 -1.18187e-19 -2.55361e-06 -0.000279182 "
      "-4.48853e-17 -1.34732e-17 3.63975e-18 0.000583044 3.82116e-18 "
      "1.92575e-17 1.15512e-17 0.000561393\n"
      " 3.18125e-20 1.304e-19 1.24658e-18 -0.000236757 1.06257e-19 "
      "-3.85377e-19 -1.07791e-18 0.000571075 -1.10655e-18 4.41282e-18 "
      "-1.34732e-17 -4.87054e-17 0.000933746 2.20928e-18 -2.02725e-17 "
      "3.15745e-18 -0.00101792 -1.5996e-17\n"
      "-9.41754e-20 -7.25741e-20 -0.000221617 2.35927e-19 1.68036e-19 "
      "1.32678e-19 6.09088e-05 -4.51091e-19 -2.46058e-19 -3.00215e-18 "
      "3.63975e-18 0.000933746 -3.92514e-17 -3.45245e-18 -1.02069e-17 "
      "-0.00105994 3.92872e-18 -1.07084e-17\n"
      " 5.47042e-19 0.000130282 -1.1498e-19 -1.73459e-19 -7.4701e-19 "
      "-0.000283019 2.02004e-19 5.55723e-19 6.94632e-19 3.77869e-18 "
      "0.000583044 2.20928e-18 -3.45245e-18 -3.15059e-17 0.000450629 "
      "3.10939e-18 9.77337e-18 -2.34777e-18\n"
      " 0.000162848 2.05121e-19 3.87322e-19 -1.0818e-19 -0.000198317 "
      "-5.60102e-19 -3.01332e-19 2.1991e-19 4.23149e-05 -0.00107761 "
      "3.82116e-18 -2.02725e-17 -1.02069e-17 0.000450629 -6.30261e-17 "
      "3.41391e-19 1.26605e-18 -0.00128728\n"
      "-2.16955e-20 -9.17829e-20 -1.03433e-18 0.000125724 -1.14083e-19 "
      "2.75892e-19 1.03987e-18 -0.000311016 1.05022e-18 3.97249e-19 "
      "1.92575e-17 3.15745e-18 -0.00105994 3.10939e-18 3.41391e-19 -5.5022e-17 "
      "0.00157102 2.37117e-18\n"
      " 2.98515e-19 1.76009e-19 0.000653992 -4.89225e-19 -5.13226e-19 "
      "-3.05564e-19 -0.000247983 1.48718e-18 7.37562e-19 1.00303e-17 "
      "1.15512e-17 -0.00101792 3.92872e-18 9.77337e-18 1.26605e-18 0.00157102 "
      "-4.85784e-17 7.46174e-19\n"
      "-3.53837e-19 -6.01776e-05 9.72262e-19 2.37476e-19 6.74611e-19 "
      "0.000153394 -1.04095e-18 -7.27807e-19 -1.53758e-18 -7.52114e-18 "
      "0.000561393 -1.5996e-17 -1.07084e-17 -2.34777e-18 -0.00128728 "
      "2.37117e-18 7.46174e-19 -4.87189e-17";

  ref_string[2] =
      " 0.000763723 5.40212e-18 -2.82406e-17 0.000201143 -0.000126435 "
      "-7.33223e-18 -2.02354e-18 -2.41736e-05 1.26508e-05 -1.14084e-06 "
      "2.92419e-20 -2.98359e-19 0.000439466 1.57204e-06 -6.37752e-20 "
      "2.4717e-19 -0.00103123 -1.57141e-06\n"
      " 5.40212e-18 0.00074744 0.058097 -1.938e-17 3.96721e-19 -0.000150302 "
      "-0.066083 2.11639e-17 -6.05155e-18 3.24322e-20 -1.45995e-07 0.000109393 "
      "1.07735e-19 -3.02298e-20 3.77766e-07 -9.01414e-05 -3.13727e-19 "
      "-3.44263e-20\n"
      "-2.82406e-17 0.058097 0.000784973 7.76177e-18 -1.71499e-17 0.0662129 "
      "-0.000174021 5.65924e-18 -2.13179e-17 2.77435e-19 -6.15117e-05 "
      "2.34152e-06 9.65702e-20 -3.46625e-19 0.000221424 -2.00233e-06 "
      "3.24741e-20 -9.45209e-20\n"
      " 0.000201143 -1.938e-17 7.76177e-18 0.000772363 -0.000152242 "
      "2.16648e-17 5.61269e-18 -1.40429e-05 0.0438336 -0.000470951 "
      "-8.93733e-20 5.6331e-20 5.82317e-07 0.000546308 2.06945e-19 "
      "-1.50765e-22 -1.30364e-06 -0.000223298\n"
      "-0.000126435 3.96721e-19 -1.71499e-17 -0.000152242 0.000801729 "
      "-5.3772e-18 4.24194e-17 -0.0437828 -1.79119e-05 1.41615e-06 "
      "-2.57274e-20 3.43173e-19 -0.000440928 -2.06407e-06 4.49636e-20 "
      "-2.79427e-19 0.00103682 2.44447e-06\n"
      "-7.33223e-18 -0.000150302 0.0662129 2.16648e-17 -5.3772e-18 0.000832365 "
      "2.55859e-05 -1.00518e-17 -2.26815e-18 -9.13616e-20 3.61622e-07 "
      "-0.000374926 -2.13749e-19 8.62e-20 -9.94085e-07 0.000315638 6.33917e-19 "
      "9.10312e-20\n"
      "-2.02354e-18 -0.066083 -0.000174021 5.61269e-18 4.24194e-17 2.55859e-05 "
      "0.000836181 2.79135e-18 -9.50919e-18 -1.54479e-19 3.13903e-05 "
      "-1.91144e-06 -6.07816e-20 1.65087e-19 -0.000132339 1.89262e-06 "
      "-1.03188e-19 2.83554e-19\n"
      "-2.41736e-05 2.11639e-17 5.65924e-18 -1.40429e-05 -0.0437828 "
      "-1.00518e-17 2.79135e-18 0.000931744 -1.2951e-05 0.000872958 "
      "2.27293e-19 -2.04498e-20 -1.04977e-06 -0.000975911 -5.30941e-19 "
      "-1.23036e-19 3.33804e-06 0.000298789\n"
      " 1.26508e-05 -6.05155e-18 -2.13179e-17 0.0438336 -1.79119e-05 "
      "-2.26815e-18 -9.50919e-18 -1.2951e-05 0.000930169 -8.0589e-07 "
      "-3.93507e-20 3.36471e-19 3.80322e-05 1.6191e-06 1.45962e-19 -3.3523e-19 "
      "-0.000202327 -3.73838e-06\n"
      "-1.14084e-06 3.24322e-20 2.77435e-19 -0.000470951 1.41615e-06 "
      "-9.13616e-20 -1.54479e-19 0.000872958 -8.0589e-07 -0.000967196 "
      "1.57764e-18 -1.32157e-17 0.00212322 0.000144172 -2.16816e-17 "
      "8.52557e-18 -0.000836608 -1.43171e-05\n"
      " 2.92419e-20 -1.45995e-07 -6.15117e-05 -8.93733e-20 -2.57274e-20 "
      "3.61622e-07 3.13903e-05 2.27293e-19 -3.93507e-20 1.57764e-18 "
      "-0.000944085 3.59446e-05 -3.39514e-18 1.18454e-17 0.000165601 "
      "-0.0018612 -2.39501e-17 -4.17059e-17\n"
      "-2.98359e-19 0.000109393 2.34152e-06 5.6331e-20 3.43173e-19 "
      "-0.000374926 -1.91144e-06 -2.04498e-20 3.36471e-19 -1.32157e-17 "
      "3.59446e-05 -0.000997514 1.38405e-17 -1.23808e-17 0.00282045 "
      "0.000193125 -2.18309e-18 8.45631e-18\n"
      " 0.000439466 1.07735e-19 9.65702e-20 5.82317e-07 -0.000440928 "
      "-2.13749e-19 -6.07816e-20 -1.04977e-06 3.80322e-05 0.00212322 "
      "-3.39514e-18 1.38405e-17 -0.000977976 -0.00200583 2.23934e-17 "
      "1.29076e-17 1.89954e-05 -0.00210035\n"
      " 1.57204e-06 -3.02298e-20 -3.46625e-19 0.000546308 -2.06407e-06 "
      "8.62e-20 1.65087e-19 -0.000975911 1.6191e-06 0.000144172 1.18454e-17 "
      "-1.23808e-17 -0.00200583 -0.00101142 9.18044e-18 6.04844e-18 0.00337152 "
      "2.27886e-05\n"
      "-6.37752e-20 3.77766e-07 0.000221424 2.06945e-19 4.49636e-20 "
      "-9.94085e-07 -0.000132339 -5.30941e-19 1.45962e-19 -2.16816e-17 "
      "0.000165601 0.00282045 2.23934e-17 9.18044e-18 -0.00104623 0.000278571 "
      "-1.29488e-18 -4.94696e-19\n"
      " 2.4717e-19 -9.01414e-05 -2.00233e-06 -1.50765e-22 -2.79427e-19 "
      "0.000315638 1.89262e-06 -1.23036e-19 -3.3523e-19 8.52557e-18 -0.0018612 "
      "0.000193125 1.29076e-17 6.04844e-18 0.000278571 -0.00105004 3.90914e-19 "
      "-2.07673e-18\n"
      " -0.00103123 -3.13727e-19 3.24741e-20 -1.30364e-06 0.00103682 "
      "6.33917e-19 -1.03188e-19 3.33804e-06 -0.000202327 -0.000836608 "
      "-2.39501e-17 -2.18309e-18 1.89954e-05 0.00337152 -1.29488e-18 "
      "3.90914e-19 -0.00115673 -3.94179e-05\n"
      "-1.57141e-06 -3.44263e-20 -9.45209e-20 -0.000223298 2.44447e-06 "
      "9.10312e-20 2.83554e-19 0.000298789 -3.73838e-06 -1.43171e-05 "
      "-4.17059e-17 8.45631e-18 -0.00210035 2.27886e-05 -4.94696e-19 "
      "-2.07673e-18 -3.94179e-05 -0.00115522";

  ref_string[3] =
      " -0.00771459 -1.77597e-18 -3.20792e-18 2.07788e-05 0.00106957 "
      "-8.48856e-19 -5.66528e-18 -3.33679e-06 -0.000349271 0.00042977 "
      "2.27517e-21 -8.88604e-20 -4.08361e-06 -0.000874484 -5.09229e-21 "
      "6.92328e-20 8.15166e-06 0.00186155\n"
      "-1.77597e-18 -0.00704949 -1.34933e-05 -5.3934e-18 1.66035e-18 "
      "0.000352228 -8.22431e-06 4.40752e-18 2.1232e-19 6.17308e-21 -0.00011235 "
      "2.00519e-06 1.34036e-20 -8.25109e-21 0.000243261 -9.08221e-07 "
      "-4.67211e-20 5.12625e-21\n"
      "-3.20792e-18 -1.34933e-05 -0.00852371 -6.84319e-19 1.30191e-18 "
      "2.15141e-05 0.0011608 1.48149e-18 5.14438e-18 8.71072e-20 -2.29569e-06 "
      "-0.000937819 1.32992e-20 -1.4671e-19 5.83678e-06 0.00128329 "
      "-3.23934e-20 2.49617e-19\n"
      " 2.07788e-05 -5.3934e-18 -6.84319e-19 -0.00741563 -9.84874e-06 "
      "3.91964e-18 -2.44264e-18 0.0658271 -1.40706e-05 3.61203e-06 "
      "-1.56246e-20 1.00108e-20 0.000579775 -3.91612e-06 3.75201e-20 "
      "-4.89827e-21 -0.000987805 3.01259e-07\n"
      " 0.00106957 1.66035e-18 1.30191e-18 -9.84874e-06 -0.00840001 "
      "1.56244e-18 3.4552e-18 8.24209e-06 -0.0647473 -0.000941901 -2.49879e-21 "
      "1.45503e-19 4.72525e-06 0.00163956 5.60812e-21 -1.20092e-19 "
      "-1.05454e-05 -0.00294678\n"
      "-8.48856e-19 0.000352228 2.15141e-05 3.91964e-18 1.56244e-18 -0.0945527 "
      "5.67416e-06 -9.90221e-19 7.45901e-19 -1.43521e-20 0.000240009 "
      "-5.09719e-06 -3.28852e-20 1.96639e-20 -0.000527982 2.63882e-06 "
      "1.14723e-19 -1.38149e-20\n"
      "-5.66528e-18 -8.22431e-06 0.0011608 -2.44264e-18 3.4552e-18 5.67416e-06 "
      "0.0783776 -6.96327e-19 -9.25382e-19 -6.85503e-20 1.24552e-06 0.00142252 "
      "-5.31666e-21 1.17508e-19 -3.5641e-06 -0.00149684 1.15075e-20 "
      "-2.09893e-19\n"
      "-3.33679e-06 4.40752e-18 1.48149e-18 0.0658271 8.24209e-06 -9.90221e-19 "
      "-6.96327e-19 -0.00828105 -2.42527e-06 -7.20841e-06 4.68701e-20 "
      "-2.99137e-20 -0.00094624 8.73493e-06 -1.16657e-19 1.58867e-20 "
      "0.00178345 -3.21703e-06\n"
      "-0.000349271 2.1232e-19 5.14438e-18 -1.40706e-05 -0.0647473 7.45901e-19 "
      "-9.25382e-19 -2.42527e-06 -0.00868438 0.00224633 -1.90674e-21 "
      "-2.10636e-19 -1.67686e-06 -0.00339694 4.86672e-21 1.935e-19 7.26058e-06 "
      "0.00489088\n"
      " 0.00042977 6.17308e-21 8.71072e-20 3.61203e-06 -0.000941901 "
      "-1.43521e-20 -6.85503e-20 -7.20841e-06 0.00224633 -0.00374038 "
      "1.24565e-18 -3.30341e-19 -0.000376362 -0.00912856 -7.01089e-19 "
      "-2.5784e-18 7.22143e-05 0.00602099\n"
      " 2.27517e-21 -0.00011235 -2.29569e-06 -1.56246e-20 -2.49879e-21 "
      "0.000240009 1.24552e-06 4.68701e-20 -1.90674e-21 1.24565e-18 -0.0104098 "
      "0.000271542 -1.4343e-18 -3.77324e-19 0.000349208 0.000167767 "
      "1.12369e-18 -2.14753e-18\n"
      "-8.88604e-20 2.00519e-06 -0.000937819 1.00108e-20 1.45503e-19 "
      "-5.09719e-06 0.00142252 -2.99137e-20 -2.10636e-19 -3.30341e-19 "
      "0.000271542 0.00362349 1.22238e-18 1.67257e-18 -0.000322745 -0.0115724 "
      "-4.78417e-19 1.98736e-18\n"
      "-4.08361e-06 1.34036e-20 1.32992e-20 0.000579775 4.72525e-06 "
      "-3.28852e-20 -5.31666e-21 -0.00094624 -1.67686e-06 -0.000376362 "
      "-1.4343e-18 1.22238e-18 -0.0100334 8.6304e-05 1.0966e-18 2.13534e-18 "
      "-0.00494364 0.000187168\n"
      "-0.000874484 -8.25109e-21 -1.4671e-19 -3.91612e-06 0.00163956 "
      "1.96639e-20 1.17508e-19 8.73493e-06 -0.00339694 -0.00912856 "
      "-3.77324e-19 1.67257e-18 8.6304e-05 0.0038285 -7.45853e-19 4.13726e-19 "
      "-0.000193665 -0.00597263\n"
      "-5.09229e-21 0.000243261 5.83678e-06 3.75201e-20 5.60812e-21 "
      "-0.000527982 -3.5641e-06 -1.16657e-19 4.86672e-21 -7.01089e-19 "
      "0.000349208 -0.000322745 1.0966e-18 -7.45853e-19 -0.00223485 "
      "4.79663e-06 1.30869e-18 -4.38832e-19\n"
      " 6.92328e-20 -9.08221e-07 0.00128329 -4.89827e-21 -1.20092e-19 "
      "2.63882e-06 -0.00149684 1.58867e-20 1.935e-19 -2.5784e-18 0.000167767 "
      "-0.0115724 2.13534e-18 4.13726e-19 4.79663e-06 -0.00392453 3.78512e-19 "
      "1.4209e-18\n"
      " 8.15166e-06 -4.67211e-20 -3.23934e-20 -0.000987805 -1.05454e-05 "
      "1.14723e-19 1.15075e-20 0.00178345 7.26058e-06 7.22143e-05 1.12369e-18 "
      "-4.78417e-19 -0.00494364 -0.000193665 1.30869e-18 3.78512e-19 "
      "-0.00594456 -6.65368e-07\n"
      " 0.00186155 5.12625e-21 2.49617e-19 3.01259e-07 -0.00294678 "
      "-1.38149e-20 -2.09893e-19 -3.21703e-06 0.00489088 0.00602099 "
      "-2.14753e-18 1.98736e-18 0.000187168 -0.00597263 -4.38832e-19 "
      "1.4209e-18 -6.65368e-07 0.00117692";

  std::array<int, 4> indeces = {0, 1, 3, 12};
  for (Index i = 0; i < 4; i++) {
    ref[i] = ReadMatrixFromString(ref_string[i]);
  }

  for (Index i = 0; i < 4; i++) {
    bool check = ref[i].isApprox(threec[indeces[i]].FullMatrix(), 1e-5);
    BOOST_CHECK_EQUAL(check, true);
    if (!check) {
      std::cout << "ref " << indeces[i] << std::endl;
      std::cout << ref[i] << std::endl;
      std::cout << "result " << indeces[i] << std::endl;
      std::cout << threec[indeces[i]].FullMatrix() << std::endl;
    }
  }
}
BOOST_AUTO_TEST_SUITE_END()
